package wxcloud

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/mars/internal/admin/core/domain"
	"github.com/mars/internal/pkg/wxcloud"
)

const cartCollection = "cart"

type CartGatewayImpl struct {
	wxcloud   *wxcloud.WxCloudClient
	productGw domain.ProductGateway
}

func NewCartGateway(wxcloud *wxcloud.WxCloudClient, productGw domain.ProductGateway) domain.CartGateway {
	return &CartGatewayImpl{
		wxcloud:   wxcloud,
		productGw: productGw,
	}
}

// GetCartList 获取购物车列表
func (c *CartGatewayImpl) GetCartList(ctx context.Context, params domain.CartQueryParams) ([]domain.CartItem, int64, error) {
	queryBuilder := wxcloud.NewQueryBuilder(cartCollection)

	// 添加筛选条件
	if params.OpenID != "" {
		queryBuilder = queryBuilder.Where("openid", params.OpenID)
	}

	if params.ProductID != "" {
		queryBuilder = queryBuilder.Where("productId", params.ProductID)
	}

	if params.Status != "" {
		queryBuilder = queryBuilder.Where("status", string(params.Status))
	}

	// 添加关键字搜索
	if params.Keyword != "" {
		// 在微信云数据库中，需要使用正则表达式进行模糊搜索
		queryBuilder = queryBuilder.Where("$or", []interface{}{
			map[string]interface{}{
				"openid": map[string]interface{}{
					"$regex":   params.Keyword,
					"$options": "i",
				},
			},
		})
	}

	// 添加排序
	if params.Sort != "" {
		if params.Order == "asc" {
			queryBuilder = queryBuilder.OrderBy(params.Sort, "asc")
		} else {
			queryBuilder = queryBuilder.OrderBy(params.Sort, "desc")
		}
	} else {
		queryBuilder = queryBuilder.OrderBy("createTime", "desc") // 默认按创建时间倒序
	}

	// 添加分页
	offset := (params.Page - 1) * params.PageSize
	queryBuilder = queryBuilder.Skip(offset).Limit(params.PageSize)

	// 执行查询
	query := queryBuilder.BuildQueryString()
	resp, err := c.wxcloud.DatabaseQuery(ctx, c.wxcloud.EnvId(), query)
	if err != nil {
		return nil, 0, fmt.Errorf("failed to query cart list: %w", err)
	}

	var cartItems []domain.CartItem
	for _, item := range resp.Data {
		var cartItem domain.CartItem
		if err := json.Unmarshal([]byte(item), &cartItem); err == nil {
			// 获取关联的产品信息
			if product, err := c.productGw.GetProduct(ctx, cartItem.ProductID); err == nil {
				cartItem.ProductInfo = product
			}
			cartItems = append(cartItems, cartItem)
		} else {
			return nil, 0, err
		}
	}

	return cartItems, int64(resp.Pager.Total), nil
}

// GetCartItem 根据ID获取购物车项详情
func (c *CartGatewayImpl) GetCartItem(ctx context.Context, cartID string) (*domain.CartItem, error) {
	query := wxcloud.NewQueryBuilder(cartCollection).
		Where("_id", cartID).
		Limit(1).
		BuildQueryString()

	resp, err := c.wxcloud.DatabaseQuery(ctx, c.wxcloud.EnvId(), query)
	if err != nil {
		return nil, fmt.Errorf("failed to query cart item: %w", err)
	}

	if len(resp.Data) == 0 {
		return nil, fmt.Errorf("cart item not found with id: %s", cartID)
	}

	var cartItem domain.CartItem
	if err := json.Unmarshal([]byte(resp.Data[0]), &cartItem); err != nil {
		return nil, err
	}

	// 获取关联的产品信息
	if product, err := c.productGw.GetProduct(ctx, cartItem.ProductID); err == nil {
		cartItem.ProductInfo = product
	}

	return &cartItem, nil
}

// GetUserCartItems 获取用户的购物车列表
func (c *CartGatewayImpl) GetUserCartItems(ctx context.Context, openid string) ([]domain.CartItem, error) {
	query := wxcloud.NewQueryBuilder(cartCollection).
		Where("openid", openid).
		Where("status", string(domain.CartStatusActive)).
		OrderBy("createTime", "desc").
		BuildQueryString()

	resp, err := c.wxcloud.DatabaseQuery(ctx, c.wxcloud.EnvId(), query)
	if err != nil {
		return nil, fmt.Errorf("failed to query user cart items: %w", err)
	}

	var cartItems []domain.CartItem
	for _, item := range resp.Data {
		var cartItem domain.CartItem
		if err := json.Unmarshal([]byte(item), &cartItem); err == nil {
			// 获取关联的产品信息
			if product, err := c.productGw.GetProduct(ctx, cartItem.ProductID); err == nil {
				cartItem.ProductInfo = product
			}
			cartItems = append(cartItems, cartItem)
		} else {
			return nil, err
		}
	}

	return cartItems, nil
}

// GetCartItemsByProduct 根据产品ID获取购物车项列表
func (c *CartGatewayImpl) GetCartItemsByProduct(ctx context.Context, productID string) ([]domain.CartItem, error) {
	query := wxcloud.NewQueryBuilder(cartCollection).
		Where("productId", productID).
		Where("status", string(domain.CartStatusActive)).
		OrderBy("createTime", "desc").
		BuildQueryString()

	resp, err := c.wxcloud.DatabaseQuery(ctx, c.wxcloud.EnvId(), query)
	if err != nil {
		return nil, fmt.Errorf("failed to query cart items by product: %w", err)
	}

	var cartItems []domain.CartItem
	for _, item := range resp.Data {
		var cartItem domain.CartItem
		if err := json.Unmarshal([]byte(item), &cartItem); err == nil {
			// 获取关联的产品信息
			if product, err := c.productGw.GetProduct(ctx, cartItem.ProductID); err == nil {
				cartItem.ProductInfo = product
			}
			cartItems = append(cartItems, cartItem)
		} else {
			return nil, err
		}
	}

	return cartItems, nil
}

// GetCartItemsByStatus 根据状态获取购物车项列表
func (c *CartGatewayImpl) GetCartItemsByStatus(ctx context.Context, status domain.CartStatus) ([]domain.CartItem, error) {
	query := wxcloud.NewQueryBuilder(cartCollection).
		Where("status", string(status)).
		OrderBy("createTime", "desc").
		BuildQueryString()

	resp, err := c.wxcloud.DatabaseQuery(ctx, c.wxcloud.EnvId(), query)
	if err != nil {
		return nil, fmt.Errorf("failed to query cart items by status: %w", err)
	}

	var cartItems []domain.CartItem
	for _, item := range resp.Data {
		var cartItem domain.CartItem
		if err := json.Unmarshal([]byte(item), &cartItem); err == nil {
			// 获取关联的产品信息
			if product, err := c.productGw.GetProduct(ctx, cartItem.ProductID); err == nil {
				cartItem.ProductInfo = product
			}
			cartItems = append(cartItems, cartItem)
		} else {
			return nil, err
		}
	}

	return cartItems, nil
}

// GetCartStats 获取购物车统计信息
func (c *CartGatewayImpl) GetCartStats(ctx context.Context) (*domain.CartStats, error) {
	// 获取所有购物车项
	allQuery := wxcloud.NewQueryBuilder(cartCollection).BuildQueryString()
	allResp, err := c.wxcloud.DatabaseQuery(ctx, c.wxcloud.EnvId(), allQuery)
	if err != nil {
		return nil, fmt.Errorf("failed to query all cart items for stats: %w", err)
	}

	var allItems []domain.CartItem
	for _, item := range allResp.Data {
		var cartItem domain.CartItem
		if err := json.Unmarshal([]byte(item), &cartItem); err == nil {
			allItems = append(allItems, cartItem)
		}
	}

	// 计算统计信息
	stats := &domain.CartStats{
		TotalItems:    int64(len(allItems)),
		ItemsByStatus: make(map[string]int64),
	}

	userSet := make(map[string]bool)
	productQuantity := make(map[string]int64)
	var totalQuantity int64

	for _, item := range allItems {
		// 用户统计
		userSet[item.OpenID] = true

		// 状态统计
		stats.ItemsByStatus[string(item.Status)]++

		// 数量统计
		totalQuantity += int64(item.Quantity)

		// 产品热度统计
		productQuantity[item.ProductID] += int64(item.Quantity)

		// 按状态分类计数
		switch item.Status {
		case domain.CartStatusActive:
			stats.ActiveItems++
		case domain.CartStatusInactive:
			stats.InactiveItems++
		case domain.CartStatusExpired:
			stats.ExpiredItems++
		}
	}

	stats.TotalUsers = int64(len(userSet))
	stats.TotalQuantity = totalQuantity

	if stats.TotalUsers > 0 {
		stats.AvgItemsPerUser = float64(stats.TotalItems) / float64(stats.TotalUsers)
	}

	// 计算热门商品 (简化版本，实际应该根据产品信息排序)
	var topProducts []domain.ProductStat
	for productID, quantity := range productQuantity {
		topProducts = append(topProducts, domain.ProductStat{
			ProductID:   productID,
			OrderCount:  quantity, // 这里用购物车数量代替订单数
			TotalAmount: 0,        // 购物车统计中没有金额概念
		})
	}

	// 简单排序前5个热门商品
	if len(topProducts) > 5 {
		topProducts = topProducts[:5]
	}

	stats.TopProducts = topProducts

	return stats, nil
}

// SearchCartItems 搜索购物车项
func (c *CartGatewayImpl) SearchCartItems(ctx context.Context, keyword string) ([]domain.CartItem, error) {
	query := wxcloud.NewQueryBuilder(cartCollection).
		Where("$or", []interface{}{
			map[string]interface{}{
				"openid": map[string]interface{}{
					"$regex":   keyword,
					"$options": "i",
				},
			},
		}).
		OrderBy("createTime", "desc").
		BuildQueryString()

	resp, err := c.wxcloud.DatabaseQuery(ctx, c.wxcloud.EnvId(), query)
	if err != nil {
		return nil, fmt.Errorf("failed to search cart items: %w", err)
	}

	var cartItems []domain.CartItem
	for _, item := range resp.Data {
		var cartItem domain.CartItem
		if err := json.Unmarshal([]byte(item), &cartItem); err == nil {
			// 获取关联的产品信息
			if product, err := c.productGw.GetProduct(ctx, cartItem.ProductID); err == nil {
				cartItem.ProductInfo = product
			}
			cartItems = append(cartItems, cartItem)
		} else {
			return nil, err
		}
	}

	return cartItems, nil
}
